import 'package:collection/collection.dart' show IterableExtension;
import 'package:family_expense/features/bank_card/models/bank_card.dart';
import 'package:family_expense/features/bank_card/widgets/bank_shared.dart';
import 'package:family_expense/features/income_expense/constants/income_expense_type.dart';
import 'package:family_expense/features/income_expense/models/income_expense_detail.dart';
import 'package:family_expense/features/income_expense/services/income_expense_detail_service.dart';
import 'package:family_expense/features/income_expense/widgets/edit_income_expense_detail.dart';
import 'package:family_expense/features/income_expense/widgets/income_expense_detail_shared.dart';
import 'package:family_expense/features/income_expense/widgets/income_expense_detail_view.dart';
import 'package:family_expense/features/income_expense_detail_type/services/income_expense_detail_type_loader.dart';
import 'package:flutter/material.dart';
import 'package:my_flutter_core/my_flutter_core.dart';

/// To make [PagingListViewLoadController] work to reset the list the widget must be stateful.
class CreditCardBillView extends StatefulWidget {
  const CreditCardBillView(this.bankCard, this.year, this.month, {super.key});

  final BankCard bankCard;
  final int year;
  final int month;

  @override
  State<CreditCardBillView> createState() => _CreditCardBillViewState();
}

class _CreditCardBillViewState extends State<CreditCardBillView> {
  final int _pageSize = GeneralConfig.listViewPageSize;

  final IncomeExpenseDetailService _incomeExpenseDetailService =
      IncomeExpenseDetailService();

  double _billAmount = 0.0;

  // Used to reset the list once the income/expense detail updated.
  late PagingListViewLoadController _loadController;

  @override
  void initState() {
    super.initState();

    _queryCreditCardBillAmount();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(appBar: _buildAppBar(), body: _buildBody());
  }

  /// Builds app bar.
  PreferredSizeWidget _buildAppBar() {
    return AppBar(
      title: Row(
        mainAxisSize: MainAxisSize.min,
        children: [
          BankLogo(widget.bankCard.bank!),
          const SizedBox(width: 10.0),
          VerticalAppBarTitle(
            formatNumber(_billAmount),
            '${widget.bankCard.name} @ ${widget.year}-${widget.month}',
          ),
        ],
      ),
      actions: <Widget>[
        FutureBuilder<User?>(
          future: AuthStateService.instance.currentUser,
          builder: (context, userSnapshot) {
            if (userSnapshot.data?.isViewerOnly == false) {
              return TextButton(
                onPressed: _billAmount != 0 ? _gotoRepayment : null,
                child: Text(
                  '还款',
                  style: TextStyle(
                    color: calculateContrastingColor(
                      Theme.of(context).appBarTheme.backgroundColor!,
                    ),
                  ),
                ),
              );
            }

            return Container();
          },
        ),
      ],
    );
  }

  /// Builds main body.
  Widget _buildBody() {
    return PagingListView(
      padding: const EdgeInsets.only(top: 10.0),
      pageSize: _pageSize,
      getLoadController: (loadController) => _loadController = loadController,
      retrieveData: (pageIndex) =>
          _incomeExpenseDetailService.queryCreditCardBill(
            _pageSize,
            pageIndex!,
            widget.bankCard.id!,
            DateTime(
              widget.year,
              widget.month,
              int.parse(widget.bankCard.statementDate!),
            ),
          ),
      refreshed: _queryCreditCardBillAmount,
      itemBuilder: (context, entry, index) => _buildDetail(entry),
    );
  }

  Future<void> _queryCreditCardBillAmount() async {
    final res = await _incomeExpenseDetailService.queryCreditCardBillAmount(
      widget.bankCard.id!,
      DateTime(
        widget.year,
        widget.month,
        int.parse(widget.bankCard.statementDate!),
      ),
    );

    if (mounted) {
      setState(() => _billAmount = res);
    }
  }

  /// Builds the detail list tile.
  Widget _buildDetail(IncomeExpenseDetail item) {
    return IncomeExpenseDetailListTile(item, () async {
      final dataUpdated = await NavigatorHelper.push<bool>(
        context,
        IncomeExpenseDetailView(item.id!),
      );

      // If the income/expense details is updated we need to refresh the list and recalculate bill ammount.
      if (dataUpdated == true) {
        final res = await _incomeExpenseDetailService.queryCreditCardBillAmount(
          widget.bankCard.id!,
          DateTime(
            widget.year,
            widget.month,
            int.parse(widget.bankCard.statementDate!),
          ),
        );

        if (mounted) {
          setState(() => _billAmount = res);
        }

        _loadController.reset();
      }
    }, displayIncomeExpenseDate: true);
  }

  /// Goes to credit card repayment view with prepared data.
  Future<void> _gotoRepayment() async {
    // Gets credit card repayment type value.
    // Uses orElse parameter to slient 'No Element' error if no match found.
    final creditCardRepaymentType =
        IncomeExpenseDetailTypeLoader.getDetailTypes(IncomeExpenseType.expense)
            .firstWhereOrNull(
              (p) =>
                  p.name!.toUpperCase().contains('REPAYMENT') ||
                  p.title!.contains('信用卡还款'),
            )
            ?.name;

    // Goes to credit card repayment view with prepared data.
    NavigatorHelper.push(
      context,
      EditIncomeExpenseDetail(
        incomeExpenseDetail: IncomeExpenseDetail(
          incomeExpenseDate: getCurrentDateTime(),
          detailType: creditCardRepaymentType,
          amount: _billAmount,
          details: '${widget.bankCard.bank!.name}信用卡还款',
        ),
      ),
    );
  }
}
